home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_100
/
176_01
/
xlcont.c
< prev
next >
Wrap
Text File
|
1985-12-25
|
19KB
|
878 lines
/* xlcont - xlisp control built-in functions */
/* Copyright (c) 1985, by David Michael Betz
All Rights Reserved
Permission is granted for unrestricted non-commercial use */
#include "xlisp.h"
/* external variables */
extern NODE ***xlstack,*xlenv,*xlvalue;
extern NODE *s_unbound;
extern NODE *s_evalhook,*s_applyhook;
extern NODE *true;
/* external routines */
extern NODE *xlxeval();
/* forward declarations */
FORWARD NODE *let();
FORWARD NODE *prog();
FORWARD NODE *progx();
FORWARD NODE *doloop();
/* xcond - built-in function 'cond' */
NODE *xcond(args)
NODE *args;
{
NODE ***oldstk,*arg,*list,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,&list,NULL);
/* initialize */
arg = args;
/* initialize the return value */
val = NIL;
/* find a predicate that is true */
while (arg) {
/* get the next conditional */
list = xlmatch(LIST,&arg);
/* evaluate the predicate part */
if (val = xlevarg(&list)) {
/* evaluate each expression */
while (list)
val = xlevarg(&list);
/* exit the loop */
break;
}
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the value */
return (val);
}
/* xcase - built-in function 'case' */
NODE *xcase(args)
NODE *args;
{
NODE ***oldstk,*key,*arg,*clause,*list,*val;
/* create a new stack frame */
oldstk = xlsave(&key,&arg,&clause,NULL);
/* initialize */
arg = args;
/* get the key expression */
key = xlevarg(&arg);
/* initialize the return value */
val = NIL;
/* find a case that matches */
while (arg) {
/* get the next case clause */
clause = xlmatch(LIST,&arg);
/* compare the key list against the key */
if ((list = xlarg(&clause)) == true ||
(listp(list) && keypresent(key,list)) ||
eql(key,list)) {
/* evaluate each expression */
while (clause)
val = xlevarg(&clause);
/* exit the loop */
break;
}
}
/* restore the previous stack frame */
xlstack = oldstk;
/* return the value */
return (val);
}
/* keypresent - check for the presence of a key in a list */
LOCAL int keypresent(key,list)
NODE *key,*list;
{
for (; consp(list); list = cdr(list))
if (eql(car(list),key))
return (TRUE);
return (FALSE);
}
/* xand - built-in function 'and' */
NODE *xand(args)
NODE *args;
{
NODE ***oldstk,*arg,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,NULL);
/* initialize */
arg = args;
val = true;
/* evaluate each argument */
while (arg)
/* get the next argument */
if ((val = xlevarg(&arg)) == NIL)
break;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result value */
return (val);
}
/* xor - built-in function 'or' */
NODE *xor(args)
NODE *args;
{
NODE ***oldstk,*arg,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,NULL);
/* initialize */
arg = args;
val = NIL;
/* evaluate each argument */
while (arg)
if ((val = xlevarg(&arg)))
break;
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result value */
return (val);
}
/* xif - built-in function 'if' */
NODE *xif(args)
NODE *args;
{
NODE ***oldstk,*testexpr,*thenexpr,*elseexpr,*val;
/* create a new stack frame */
oldstk = xlsave(&testexpr,&thenexpr,&elseexpr,NULL);
/* get the test expression, then clause and else clause */
testexpr = xlarg(&args);
thenexpr = xlarg(&args);
elseexpr = (args ? xlarg(&args) : NIL);
xllastarg(args);
/* evaluate the appropriate clause */
val = xleval(xleval(testexpr) ? thenexpr : elseexpr);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the last value */
return (val);
}
/* xlet - built-in function 'let' */
NODE *xlet(args)
NODE *args;
{
return (let(args,TRUE));
}
/* xletstar - built-in function 'let*' */
NODE *xletstar(args)
NODE *args;
{
return (let(args,FALSE));
}
/* let - common let routine */
LOCAL NODE *let(args,pflag)
NODE *args; int pflag;
{
NODE ***oldstk,*newenv,*arg,*val;
/* create a new stack frame */
oldstk = xlsave(&newenv,&arg,NULL);
/* initialize */
arg = args;
/* create a new environment frame */
newenv = xlframe(xlenv);
/* get the list of bindings and bind the symbols */
if (!pflag) xlenv = newenv;
dobindings(xlmatch(LIST,&arg),newenv);
if (pflag) xlenv = newenv;
/* execute the code */
for (val = NIL; arg; )
val = xlevarg(&arg);
/* unbind the arguments */
xlenv = cdr(xlenv);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xprog - built-in function 'prog' */
NODE *xprog(args)
NODE *args;
{
return (prog(args,TRUE));
}
/* xprogstar - built-in function 'prog*' */
NODE *xprogstar(args)
NODE *args;
{
return (prog(args,FALSE));
}
/* prog - common prog routine */
LOCAL NODE *prog(args,pflag)
NODE *args; int pflag;
{
NODE ***oldstk,*newenv,*arg,*val;
/* create a new stack frame */
oldstk = xlsave(&newenv,&arg,NULL);
/* initialize */
arg = args;
/* create a new environment frame */
newenv = xlframe(xlenv);
/* get the list of bindings and bind the symbols */
if (!pflag) xlenv = newenv;
dobindings(xlmatch(LIST,&arg),newenv);
if (pflag) xlenv = newenv;
/* execute the code */
tagblock(arg,&val);
/* unbind the arguments */
xlenv = cdr(xlenv);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the result */
return (val);
}
/* xgo - built-in function 'go' */
NODE *xgo(args)
NODE *args;
{
NODE *label;
/* get the target label */
label = xlarg(&args);
xllastarg(args);
/* transfer to the label */
xlgo(label);
}
/* xreturn - built-in function 'return' */
NODE *xreturn(args)
NODE *args;
{
NODE *val;
/* get the return value */
val = (args ? xlarg(&args) : NIL);
xllastarg(args);
/* return from the inner most block */
xlreturn(val);
}
/* xprog1 - built-in function 'prog1' */
NODE *xprog1(args)
NODE *args;
{
return (progx(args,1));
}
/* xprog2 - built-in function 'prog2' */
NODE *xprog2(args)
NODE *args;
{
return (progx(args,2));
}
/* progx - common progx code */
LOCAL NODE *progx(args,n)
NODE *args; int n;
{
NODE ***oldstk,*arg,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,&val,NULL);
/* initialize */
arg = args;
/* evaluate the first n expressions */
while (n--)
val = xlevarg(&arg);
/* evaluate each remaining argument */
while (arg)
xlevarg(&arg);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the last test expression value */
return (val);
}
/* xprogn - built-in function 'progn' */
NODE *xprogn(args)
NODE *args;
{
NODE ***oldstk,*arg,*val;
/* create a new stack frame */
oldstk = xlsave(&arg,NULL);
/* initialize */
arg = args;
/* evaluate each remaining argument */
for (val = NIL; arg; )
val = xlevarg(&arg);
/* restore the previous stack frame */
xlstack = oldstk;
/* return the last test expression value */
return (val);
}
/* xdo - built-in function 'do' */
NODE *xdo(args)
NODE *args;
{
return (doloop(args,TRUE));
}
/* xdostar - built-in function 'do*' */
NODE *xdostar(args)
NODE *args;
{
return (doloop(args,FALSE));
}
/* doloop - common do routine */
LOCAL NODE *doloop(args,pflag)
NODE *args; int pflag;
{
NODE ***oldstk,*newenv,*arg,*blist,*clist,*test,*rval;
int rbreak;
/* create a new stack frame */
oldstk = xlsave(&newenv,&arg,&bl